﻿using System.Diagnostics;
using System.Drawing.Imaging;
using System.Globalization;
using System.Net;

namespace Tetris.Game.Common
{
    //
    // 摘要:
    //     转换
    public static class ConvertEx
    {
        //
        // 摘要:
        //     转换委托
        //
        // 参数:
        //   input:
        //
        //   output:
        //
        // 类型参数:
        //   T:
        public delegate bool tran<T>(string input, out T output);

        //
        // 摘要:
        //     转换
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        //
        //   result:
        //
        // 类型参数:
        //   T:
        public static T Convert_Ex<T>(this string value, T defaultv, tran<T> result)
        {
            T output = defaultv;
            if (result(value, out output))
            {
                return output;
            }

            return defaultv;
        }

        //
        // 摘要:
        //     转换为string
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static string ToStringEx<T>(this T value, string defaultv = "")
        {
            if (value == null)
            {
                return defaultv;
            }

            return value.ToString();
        }

        //
        // 摘要:
        //     返回编码后的字符串
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        //     转换出错默认值
        public static string HtmlEncode(this string value, string defaultv = "")
        {
            if (value.IsNullOrEmpty())
            {
                return defaultv;
            }

            return WebUtility.HtmlEncode(value);
        }

        //
        // 摘要:
        //     返回解码后的字符串
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        //     转换出错默认值
        public static string HtmlDecode(this string value, string defaultv = "")
        {
            if (value.IsNullOrEmpty())
            {
                return defaultv;
            }

            return WebUtility.HtmlDecode(value);
        }

        //
        // 摘要:
        //     转换bool
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static bool ToBoolean(this string value, bool defaultv = false)
        {
            return value.Convert_Ex(defaultv, bool.TryParse);
        }

        //
        // 摘要:
        //     转换byte
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static byte ToByte(this string value, byte defaultv = 0)
        {
            return value.Convert_Ex(defaultv, byte.TryParse);
        }

        //
        // 摘要:
        //     转换char
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static char ToChar(this string value, char defaultv = '0')
        {
            return value.Convert_Ex(defaultv, char.TryParse);
        }

        //
        // 摘要:
        //     转换datetime
        //
        // 参数:
        //   value:
        public static DateTime ToDateTime(this string value)
        {
            return value.ToDateTime(DateTime.MinValue);
        }

        //
        // 摘要:
        //     转换datetime
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        //     默认值
        public static DateTime ToDateTime(this string value, DateTime defaultv)
        {
            return value.Convert_Ex(defaultv, DateTime.TryParse);
        }

        //
        // 摘要:
        //     时间转换
        //
        // 参数:
        //   value:
        //
        //   format:
        //     格式
        public static DateTime ToDateTimeExact(this string value, string format)
        {
            return value.ToDateTimeExact(format, DateTime.Now);
        }

        //
        // 摘要:
        //     时间转换
        //
        // 参数:
        //   value:
        //
        //   format:
        //     格式
        //
        //   defaultv:
        //     默认值
        public static DateTime ToDateTimeExact(this string value, string format, DateTime defaultv)
        {
            return value.ToDateTimeExact(format, CultureInfo.CurrentCulture, DateTimeStyles.None, defaultv);
        }

        //
        // 摘要:
        //     时间转换
        //
        // 参数:
        //   value:
        //
        //   format:
        //     格式
        //
        //   cultureInfo:
        //     时区信息
        public static DateTime ToDateTimeExact(this string value, string format, CultureInfo cultureInfo)
        {
            return value.ToDateTimeExact(format, cultureInfo, DateTime.Now);
        }

        //
        // 摘要:
        //     时间转换
        //
        // 参数:
        //   value:
        //
        //   format:
        //     格式
        //
        //   defaultv:
        //     默认值
        //
        //   cultureInfo:
        //     时区信息
        public static DateTime ToDateTimeExact(this string value, string format, CultureInfo cultureInfo, DateTime defaultv)
        {
            return value.ToDateTimeExact(format, cultureInfo, DateTimeStyles.None, defaultv);
        }

        //
        // 摘要:
        //     时间转换
        //
        // 参数:
        //   value:
        //
        //   format:
        //     格式
        //
        //   defaultv:
        //     默认值
        //
        //   cultureInfo:
        //     时区信息
        //
        //   dateTimeStyles:
        //     时间格式样式
        public static DateTime ToDateTimeExact(this string value, string format, CultureInfo cultureInfo, DateTimeStyles dateTimeStyles, DateTime defaultv)
        {
            DateTime result;
            if (DateTime.TryParseExact(value, format, cultureInfo, dateTimeStyles, out result))
            {
                return result;
            }

            return defaultv;
        }

        //
        // 摘要:
        //     转换datetime
        //
        // 参数:
        //   value:
        public static TimeSpan ToTimeSpan(this string value)
        {
            return value.ToTimeSpan(TimeSpan.Zero);
        }

        //
        // 摘要:
        //     转换datetime
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        //     转换失败默认值
        public static TimeSpan ToTimeSpan(this string value, TimeSpan defaultv)
        {
            return value.Convert_Ex(defaultv, TimeSpan.TryParse);
        }

        //
        // 摘要:
        //     转换decimal
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static decimal ToDecimal(this string value, decimal defaultv = 0m)
        {
            return value.Convert_Ex(defaultv, decimal.TryParse);
        }

        //
        // 摘要:
        //     转换double
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static double ToDouble(this string value, double defaultv = 0.0)
        {
            return value.Convert_Ex(defaultv, double.TryParse);
        }

        //
        // 摘要:
        //     转换short
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static short ToInt16(this string value, short defaultv = 0)
        {
            return value.Convert_Ex(defaultv, short.TryParse);
        }

        //
        // 摘要:
        //     转换int
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static int ToInt32(this string value, int defaultv = 0)
        {
            return value.Convert_Ex(defaultv, int.TryParse);
        }

        //
        // 摘要:
        //     转换long
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static long ToInt64(this string value, long defaultv = 0L)
        {
            return value.Convert_Ex(defaultv, long.TryParse);
        }

        //
        // 摘要:
        //     转换sbyte
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static sbyte ToSByte(this string value, sbyte defaultv = 0)
        {
            return value.Convert_Ex(defaultv, sbyte.TryParse);
        }

        //
        // 摘要:
        //     转换float
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static float ToSingle(this string value, float defaultv = 0f)
        {
            return value.Convert_Ex(defaultv, float.TryParse);
        }

        //
        // 摘要:
        //     转换ushort
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static ushort ToUInt16(this string value, ushort defaultv = 0)
        {
            return value.Convert_Ex(defaultv, ushort.TryParse);
        }

        //
        // 摘要:
        //     转换uint
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static uint ToUInt32(this string value, uint defaultv = 0u)
        {
            return value.Convert_Ex(defaultv, uint.TryParse);
        }

        //
        // 摘要:
        //     转换ulong
        //
        // 参数:
        //   value:
        //
        //   defaultv:
        public static ulong ToUInt64(this string value, ulong defaultv = 0uL)
        {
            return value.Convert_Ex(defaultv, ulong.TryParse);
        }

        //
        // 摘要:
        //     从时间对象转换到格式化字符串
        //
        // 参数:
        //   value:
        //
        //   format:
        //     格式化字符串
        public static string ToStringFromDateTime(this DateTime value, string format = "yyyy-MM-dd HH:mm:ss")
        {
            return value.ToString(format);
        }

        //
        // 摘要:
        //     转换guid
        //
        // 参数:
        //   value:
        public static Guid ToGuid(this string value)
        {
            return value.Convert_Ex(Guid.Empty, Guid.TryParse);
        }
        /// <summary>
        /// 将图像转Base64
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="compressionLevel">压缩级别</param>
        /// <returns></returns>
        public static string CompressToBase64(this Image bitmap, long compressionLevel)
        {
            string result = string.Empty;
            try
            {
                var bytes = bitmap.CompressToBytes(compressionLevel);
                result = Convert.ToBase64String(bytes);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message + ";" + ex.StackTrace);
            }
            return result;
        }
        public static byte[] CompressToBytes(this Image bitmap, long compressionLevel)
        {
            var encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, compressionLevel);

            var jpegCodecInfo = "image/jpeg".GetEncoderInfo();
            byte[] compressedData;

            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, jpegCodecInfo, encoderParams);
                compressedData = stream.ToArray();
            }
            return compressedData;
        }
        public static ImageCodecInfo GetEncoderInfo(this string mimeType)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.MimeType == mimeType)
                {
                    return codec;
                }
            }
            return null;
        }
    }
}
